假設你被分配到用 C 語言編寫一個檔案系統。struct file_item 代表一個檔案或目錄。data union可以包含檔案的內容(作為字串)或一個指向子 file_item 的指標陣列。針對這個問題,假設指標的長度為 4 個位元組。
#include <stdbool.h>
typedef struct file_item {
    char *name;
    bool is_directory;
    file_item_data data;
} file_item;
typedef union file_item_data {
    char contents[X];
    struct file_item *children[16];
} file_item_data;
/* Copies all characters from src to dest including the NULL terminator */
char *strcpy(char *dest, const char *src);
typedef struct file_item:
file_item 的結構體,這個結構體用來表示一個檔案或目錄。char *name;:儲存檔案或目錄的名稱,為一個指向字串的指標。bool is_directory;:表示該項目是否為目錄。如果是目錄,則為 true;如果是檔案,則為 false。file_item_data data;:是一個 union 類型,根據 is_directory 的值,決定是儲存檔案的內容還是子目錄指標。typedef union file_item_data:
file_item_data 根據檔案類型儲存不同的資料:
char contents[X];:如果該項目是檔案,則 contents 儲存檔案的內容,X 代表內容的大小(未指定大小,可能要根據實際需求定義)。struct file_item *children[16];:如果該項目是目錄,則 children 會存放指向其他 file_item 結構體的指標,這些指標代表目錄下的子項目。最多可以包含 16 個子項目。strcpy 函式:
strcpy 是一個標準函式,目的是將來源字串 src 複製到目標字串 dest 中。它會將字串的所有字元,包括結尾的 NULL 終止符,一併複製到 dest。我們將 X 設定為不增加 union 大小的最大值。那麼,我們可以在單一檔案中儲存的字串最大長度是多少呢?
B01 = 63
union 的大小由其最大的元素決定,忽略對齊規則(這裡不考慮)。在 32 位系統中,指標是 32 位(4 個位元組)。children 是一個包含 16 個指標的陣列,佔用的空間為 16 × 4 = 64 位元組。因此,我們必須確保 char contents[X] 不超過 64 位元組。由於 1 個位元組被定義為 char 的大小,將 X 設定為 64 可以達到我們的目標。結果,strlen(contents) 會返回 63,因為它不計算字串長度中的結束符號。
撰寫程式碼來建立檔案和目錄。確保即使輸入的字串在稍後被釋放,你的程式碼仍然能夠正常運作。假設輸入的字串可以適當地放入 file_item_data union 中。
/* Creates a file with the given name and contents,
 * and returns a pointer to that file.
 */
file_item *create_file(char *contents, const char *name)
{
    file_item *new_file = calloc(1, sizeof(file_item));
    new_file->name = name;
    B02 /* Fill your code here */ ;
    return new_file;
}
/* Creates a directory with the given name and no children,
 * and returns a pointer to that directory.
 */
file_item *create_directory(const char *name)
{
    file_item *new_dir = calloc(1, sizeof(file_item));
    new_dir->name = name;
    B03 /* Fill your code here */ ;
    return new_dir;
}
file_item *create_file(char *contents, const char *name)file_item *create_file(char *contents, const char *name):
contents 是檔案的內容,name 是檔案名稱。file_item *new_file = calloc(1, sizeof(file_item));:
calloc 函數分配記憶體來創建一個 file_item 結構體,並初始化為 0。calloc 分配的記憶體會自動初始化為 0,確保結構中的成員變數在分配後不含垃圾值。new_file->name = name;:
name 參數值,這樣檔案物件的 name 成員變數就會儲存檔案名稱。B02 /* Fill your code here */:
contents 複製到 new_file->data.contents,如:
strcpy(new_file->data.contents, contents);
return new_file;:
file_item 結構,代表新檔案。file_item *create_directory(const char *name)file_item *create_directory(const char *name):
name 是目錄名稱。file_item *new_dir = calloc(1, sizeof(file_item));:
calloc 函數分配記憶體來創建一個 file_item 結構體,並初始化為 0。這會確保新建的目錄在其初始化過程中是乾淨的。new_dir->name = name;:
name 參數值,這樣目錄物件的 name 成員變數就會儲存目錄名稱。B03 /* Fill your code here */:
file_item 物件為目錄,並確保 children 成員已初始化。如:
new_dir->is_directory = true;
return new_dir;:
file_item 結構,代表新目錄。你的解決方案應該是完全正確的,不能有任何記憶體洩漏,並且不應包含任何額外的行。
B02 = strcpy(new_file->data.contents, contents) (or equivalent statement)
strcpy(new_file->data.contents, contents) 將 contents 的內容複製到新檔案物件的 data.contents 中。strcpy 確保將傳入的檔案內容完整地複製到 new_file->data.contents 中,這樣即使之後原始的 contents 被釋放,檔案內容仍會保持不變。new_dir->is_directory 設定為 true,這表示該 file_item 是一個目錄,而不是檔案。is_directory 是一個布林變數,必須設定為 true 以明確標示該物件是目錄而不是檔案。file_item。這兩個部分都是必需的,分別負責複製檔案內容和標示目錄類型,確保程式正確地運作,且不會有記憶體問題。